﻿using System;
using System.Collections.Concurrent;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

class TcpReverseProxyServer
{
    private static TcpListener _tcpListener;
    private static ServerConfig _config;  // 配置文件
    private static readonly ConcurrentDictionary<string, TcpClient> _targetServers = new ConcurrentDictionary<string, TcpClient>();

    static void Main(string[] args)
    {
        // 读取服务端配置文件
        string configFilePath = "server_config.json";  // 配置文件路径
        _config = ConfigManager.LoadServerConfig(configFilePath);
        if (_config == null)
        {
            Console.WriteLine("加载服务端配置文件失败，程序即将退出。");
            return;
        }

        // 启动 TCP 监听器
        int listenPort = _config.ListenPort; // 从配置文件读取监听端口
        _tcpListener = new TcpListener(IPAddress.Any, listenPort);
        _tcpListener.Start();

        Console.WriteLine($"TCP 服务器已启动，开始监听端口 {listenPort}...");

        // 持续接受连接
        while (true)
        {
            try
            {
                var tcpClient = _tcpListener.AcceptTcpClient();
                Console.WriteLine("有新的客户端连接");

                // 启动线程处理每个客户端连接
                ThreadPool.QueueUserWorkItem(HandleClient, tcpClient);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"错误: 接受客户端连接时发生异常 - {ex.Message}");
            }
        }
    }

    private static void HandleClient(object obj)
    {
        var client = (TcpClient)obj;
        var stream = client.GetStream();
        byte[] buffer = new byte[1024];

        try
        {
            // 从客户端读取目标服务器地址
            int bytesRead = stream.Read(buffer, 0, buffer.Length);
            string targetAddress = Encoding.UTF8.GetString(buffer, 0, bytesRead);

            Console.WriteLine($"目标服务器地址：{targetAddress}");

            // 尝试连接到目标服务
            TcpClient targetClient = ConnectToTargetServer(targetAddress);  // 显式指定 TcpClient 类型
            if (targetClient == null)
            {
                Console.WriteLine("连接目标服务器失败，正在关闭客户端连接...");
                client.Close();
                return;
            }

            // 保存目标服务连接
            _targetServers[targetAddress] = targetClient;

            // 通过目标服务与客户端之间进行数据转发
            ThreadPool.QueueUserWorkItem(ForwardData, new Tuple<TcpClient, TcpClient>(client, targetClient));
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理客户端时发生错误：{ex.Message}");
        }
        finally
        {
            client.Close();
        }
    }

    private static TcpClient ConnectToTargetServer(string targetAddress)
    {
        string[] addressParts = targetAddress.Split(':');
        if (addressParts.Length != 2)
        {
            Console.WriteLine("目标地址格式错误，无法解析。");
            return null;
        }

        string targetIp = addressParts[0];
        int targetPort;

        if (!int.TryParse(addressParts[1], out targetPort))
        {
            Console.WriteLine("目标端口格式错误，无法解析。");
            return null;
        }

        try
        {
            TcpClient targetClient = new TcpClient(targetIp, targetPort);
            Console.WriteLine($"成功连接到目标服务器：{targetIp}:{targetPort}");
            return targetClient;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"连接目标服务器失败：{ex.Message}");
            return null;
        }
    }

    // 数据转发
    private static void ForwardData(object obj)
    {
        var tuple = (Tuple<TcpClient, TcpClient>)obj;
        var client = tuple.Item1;
        var targetClient = tuple.Item2;

        var clientStream = client.GetStream();
        var targetStream = targetClient.GetStream();
        byte[] buffer = new byte[1024];

        try
        {
            while (true)
            {
                // 从客户端接收数据并转发到目标服务
                int bytesRead = clientStream.Read(buffer, 0, buffer.Length);
                if (bytesRead == 0) break;

                Console.WriteLine($"正在从客户端转发 {bytesRead} 字节数据到目标服务器...");
                targetStream.Write(buffer, 0, bytesRead);
                targetStream.Flush();

                // 从目标服务接收数据并转发到客户端
                bytesRead = targetStream.Read(buffer, 0, buffer.Length);
                if (bytesRead == 0) break;

                Console.WriteLine($"正在从目标服务器转发 {bytesRead} 字节数据到客户端...");
                clientStream.Write(buffer, 0, bytesRead);
                clientStream.Flush();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"数据转发时发生错误：{ex.Message}");
        }
        finally
        {
            client.Close();
            targetClient.Close();
            Console.WriteLine("连接关闭，数据转发结束。");
        }
    }
}

// 配置文件类
class ServerConfig
{
    public int ListenPort { get; set; }
    public string TokenSecretKey { get; set; }
    public int HeartbeatIntervalSeconds { get; set; }
}

// 配置管理器类
class ConfigManager
{
    public static ServerConfig LoadServerConfig(string configFilePath)
    {
        try
        {
            string json = File.ReadAllText(configFilePath);
            return Newtonsoft.Json.JsonConvert.DeserializeObject<ServerConfig>(json);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"加载配置文件时发生错误：{ex.Message}");
            return null;
        }
    }
}
